package com.zmn.oms.admin.controller.order;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.base.price.common.dto.item.ItemDRO;
import com.zmn.base.price.common.dto.item.ItemPriceQuery;
import com.zmn.base.price.dubbo.interfaces.calculate.ItemPriceRemoteService;
import com.zmn.base.product.common.consts.BaseProductConsts;
import com.zmn.base.product.common.dto.product.ec.DefaultEcProductQuery;
import com.zmn.base.product.common.dto.product.ec.ProductBaseDRO;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dictionary.DictModel;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.oms.admin.controller.OmsBaseController;
import com.zmn.oms.business.interfaces.order.DuplicateOrderBService;
import com.zmn.oms.business.interfaces.price.PriceTableBService;
import com.zmn.oms.business.interfaces.servtype.ServItemBService;
import com.zmn.oms.business.interfaces.work.OrderWorkBService;
import com.zmn.oms.business.interfaces.work.OrderWorkListBService;
import com.zmn.oms.business.interfaces.work.epidemiccontrol.OrderWorkEpidemicControlBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.bo.order.OrderBO;
import com.zmn.oms.model.dto.order.OrderReworkDTO;
import com.zmn.oms.model.dto.work.modify.*;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.entity.work.OrderWorkQuery;
import com.zmn.oms.model.vo.price_list.PriceListVO;
import com.zmn.oms.model.vo.work.modify.OrderServItemTypeVO;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.normal.business.interfaces.order.ZsNormalOrderBService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.validation.Valid;
import java.util.List;
import java.util.Objects;

/**
 * 类描述：
 *
 * @author liuying
 * @date 2018/11/21 15:36
 */
@Controller
@RequestMapping("/order")
public class OrderController extends OmsBaseController {

    @Autowired
    private ZsNormalOrderBService zsNormalOrderBService;
    @Autowired
    private OrderWorkListBService orderWorkListBService;
    @Autowired
    private PriceTableBService priceTableBService;
    @Autowired
    private DuplicateOrderBService duplicateOrderBService;
    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    protected OrderDetailService orderDetailService;
    @Autowired
    private OrderWorkBService orderWorkBService;
    @Autowired
    private ServItemBService servItemBService;
    @Autowired
    private OrderWorkEpidemicControlBService workEpidemicControlBService;
    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private ItemPriceRemoteService itemPriceRemoteService;


    /**
     * 预约时间
     *
     * @return {string} viewName
     */
    @RequestMapping(value = "dutytime")
    public String dutytime() {
        return "order/dutyTime";
    }

    /**
     * 检验服务商
     * @return
     */
    @RequestMapping(value = "/check/company")
    public ModelAndView checkCompany(Integer plat){
        ModelAndView mv = new ModelAndView("order/checkCompany");
        if (Objects.isNull(plat)) {
            mv.addObject("platList", GlobalConsts.getPlatList());
        } else {
            mv.addObject("platList", Lists.newArrayList(new DictModel(plat, GlobalConsts.getPlatName(plat))));
        }
        return mv;
    }

    /**
     * 百度地图
     *
     * @return {string} viewName
     */
    @RequestMapping(value = "addressmap")
    public String addressMap() {
        return "order/addressMap";
    }

    /**
     * 检查返修单号
     */
    @RequestMapping(value = "/check/rework")
    @ResponseBody
    public ResultDTO checkRework(@Valid CheckReworkOrderDTO checkReworkOrderDTO) {
        try {
            OrderReworkDTO orderReworkDTO = zsNormalOrderBService.checkReworkId(checkReworkOrderDTO);
            return ResultDTO.success(orderReworkDTO);
        } catch (OmsBaseException e) {
            return ResultDTO.fail(e.getMessage());
        }
    }

    /**
     * 新增订单-检查重复单ID
     */
    @RequestMapping(value = "/check/duplicateOrder")
    @ResponseBody
    public ResultDTO checkDuplicateOrder(@Valid DuplicateOrderDTO duplicateOrderDTO) {
        try {
            logger.info("duplicateOrderDTO:{}", JSON.toJSON(duplicateOrderDTO));
            Long orderId = duplicateOrderDTO.getOrderId();
            if (Objects.isNull(orderId)) {
                if (CollectionUtils.isNotEmpty(duplicateOrderDTO.getProductIdList())) {
                    int size = duplicateOrderDTO.getProductIdList().size();
                    List<Boolean> resultList = Lists.newArrayListWithExpectedSize(size);
                    for (int i = 0; i < size; i++) {
                        Integer productId = duplicateOrderDTO.getProductIdList().get(i);
                        if (NumberUtil.isNullOrZero(productId)) {
                            resultList.add(false);
                            continue;
                        }
                        duplicateOrderDTO.setProductId(productId);
                        duplicateOrderDTO.setProductShowType(duplicateOrderDTO.getProductShowTypeList().get(i));
                        Long duplicateOrderId = duplicateOrderBService.findDuplicateOrderId(duplicateOrderDTO);
                        boolean isDuplicate = Objects.nonNull(duplicateOrderId);
                        resultList.add(isDuplicate);
                    }
                    return ResultDTO.success(resultList);
                } else {
                    Long duplicateOrderId = duplicateOrderBService.findDuplicateOrderId(duplicateOrderDTO);
                    boolean isDuplicate = Objects.nonNull(duplicateOrderId);
                    return ResultDTO.success(isDuplicate);
                }
            }

            VerifyTelephoneOrProductDTO dto = new VerifyTelephoneOrProductDTO();
            BeanMapper.copy(duplicateOrderDTO, dto);
            boolean verifyTelephoneOrProduct = duplicateOrderBService.verifyTelephoneOrProduct(dto);
            if (!verifyTelephoneOrProduct) {
                return ResultDTO.success(Boolean.FALSE);
            }
            Long duplicateOrderId = duplicateOrderBService.findDuplicateOrderId(duplicateOrderDTO);
            boolean isDuplicate = Objects.nonNull(duplicateOrderId);
            return ResultDTO.success(isDuplicate);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ResultDTO.success(false);// 返回成功，检查异常不能影响录单
        }
    }

    /**
     * 疫情管控校验
     *
     * @param countyId  区县
     * @param longitude 经度
     * @param latitude  维度
     * @return 0 正常  1 防控  2 管控  3 封控
     */
    @RequestMapping("check/epidemicControl")
    @ResponseBody
    public ResultDTO epidemicControl(Integer countyId, Double longitude, Double latitude) {
        if (Objects.isNull(longitude) || Objects.isNull(latitude)) {
            return ResultDTO.success(com.zmn.consts.GlobalConsts.NONE);
        }
        try {
            return ResultDTO.success(workEpidemicControlBService.getEpidemicControlLevel(countyId, longitude, latitude));
        } catch (Exception ex) {
            logger.error("epidemicControl error", ex);
            return ResultDTO.success(com.zmn.consts.GlobalConsts.NONE);
        }
    }

    /**
     * 统计手机号码下单数量
     */
    @RequestMapping(value = "/getOrderCountByTelephone")
    @ResponseBody
    public ResultDTO getOrderCountByTelephone(@Valid String telephone) {
        OrderWorkQuery query = new OrderWorkQuery();
        query.setConcatPhone(telephone);
        query.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        Integer count = orderWorkListBService.countOrderWorkByQuery(query);
        return ResultDTO.success(count);
    }


    @RequestMapping(value = "/getProductPriceTable")
    public ModelAndView getProductPriceTable(Integer productId,
                                             Integer cityId,
                                             Integer channelId,
                                             Integer bizType,
                                             Integer type,
                                             Integer plat,
                                             @RequestParam(required = false) Integer brandId,
                                             @RequestParam(required = false) Integer tariffType,
                                             @RequestParam(required = false) Long orderId,
                                             @RequestParam(required = false) Long workId,
                                             @RequestParam(required = false) Integer itemId) throws OmsBaseException {
        ModelAndView mv = new ModelAndView("order/productPriceTable");
        PriceListVO priceListVO = priceTableBService.getProductPriceTable(productId, cityId, channelId, bizType, brandId, tariffType, orderId, workId, type, plat, Lists.newArrayList(itemId), null);
        mv.addObject("priceListVO", priceListVO);
        return mv;
    }

    @RequestMapping(value = "/getProductPriceTableData")
    @ResponseBody
    public ResultDTO getProductPriceTableData(Integer productId,
                                             Integer cityId,
                                             Integer channelId,
                                             Integer bizType,
                                             Integer type,
                                             Integer plat,
                                             @RequestParam(required = false) Integer brandId,
                                             @RequestParam(required = false) Integer tariffType,
                                             @RequestParam(required = false) Long orderId,
                                             @RequestParam(required = false) Long workId,
                                             @RequestParam(required = false) Integer itemId) throws OmsBaseException {
        PriceListVO priceListVO = priceTableBService.getProductPriceTable(productId, cityId, channelId, bizType, brandId, tariffType, orderId, workId, type, plat, Lists.newArrayList(itemId), null);
        return ResultDTO.success(priceListVO);
    }

    /**
     * 获取工单类型以及默认服务项价格
     * @param orderServItemTypeDTO
     * @return
     */
    @RequestMapping("/getServItemTypeAndInfo")
    @ResponseBody
    public ResultDTO getOrderTypeAndProductInfo(OrderServItemTypeDTO orderServItemTypeDTO) {

        OrderServItemTypeVO servItemTypeVO = new OrderServItemTypeVO();

        // 是否修改页面调用
        boolean isUpdatePageCall = Objects.nonNull(orderServItemTypeDTO.getOrderId()) && Objects.nonNull(orderServItemTypeDTO.getWorkId());
        Integer companyId = null;
        Integer masterId = null;
        Integer beforeServItemType = null;

        if (isUpdatePageCall) {
            Integer showProductId = null;
            // 获取前台产品
            if (Objects.equals(orderServItemTypeDTO.getProductShowType(), BaseProductConsts.ERP_SHOW_TYPE)) {
                // 后端产品查询前端产品
                logger.debug("#order#price 获取前台产品列表 :{}", JSON.toJSONString(orderServItemTypeDTO.getProductId()));
                DefaultEcProductQuery defaultEcProductQuery = new DefaultEcProductQuery();
                defaultEcProductQuery.setProductIdList(Lists.newArrayList(orderServItemTypeDTO.getProductId()));
                defaultEcProductQuery.setShowType(BaseProductConsts.EC_SHOW_TYPE);
                com.zmn.common.dto2.ResponseDTO<List<ProductBaseDRO>> showProductRemote = productForeignListRemoteService.listEcErpProductByQuery(defaultEcProductQuery);
                logger.debug("#order#price 前台产品列表 :{}", JSON.toJSONString(showProductRemote));
                if (!CollectionUtils.isEmpty(showProductRemote.getData())) {
                    showProductId = showProductRemote.getData().get(0).getProductId();
                } else {
                    return ResultDTO.fail("无法获取对应前台产品");
                }
            }

            OrderBO orderBO = orderWorkBService.findOrderWork(orderServItemTypeDTO.getOrderId(), orderServItemTypeDTO.getWorkId());

            boolean isShowProductIdChanged = !Objects.equals(orderBO.getOrderWork().getShowProductId(), showProductId);
            boolean channelChanged = !NumberUtil.isNullOrZero(orderBO.getOrderWork().getChannelId()) && !Objects.equals(orderBO.getOrderWork().getChannelId(), orderBO.getOrderWork().getChannelId());
            boolean cityChanged = !NumberUtil.isNullOrZero(orderBO.getOrderWork().getCityId()) && !Objects.equals(orderBO.getOrderWork().getCityId(), orderBO.getOrderWork().getCityId());
            boolean isRework = Objects.equals(orderBO.getOrderWork().getType(), OrderConsts.ORDER_TYPE_REWORK) && Objects.equals(orderServItemTypeDTO.getType(), OrderConsts.ORDER_TYPE_REWORK);
            Integer tariffId = orderBO.getOrderProductList().get(0).getTariffId();
            if ((isShowProductIdChanged || channelChanged || cityChanged) && !isRework) {
                tariffId = null;
            }
            orderServItemTypeDTO.setTariffId(tariffId);
            orderServItemTypeDTO.setFinalPrice(orderBO.getOrderWork().getFinalPrice());

            companyId = orderBO.getOrderWork().getCompanyId();
            masterId = orderBO.getOrderWork().getMasterId();
            beforeServItemType = orderBO.getOrderWork().getServItemType();
        }

        // 检查工单服务类型
        CheckQuotationTypeOrderDTO checkQuotationTypeOrderDTO = CheckQuotationTypeOrderDTO
                .builder()
                .bizType(orderServItemTypeDTO.getBizType())
                .channelId(orderServItemTypeDTO.getChannelId())
                .cityId(orderServItemTypeDTO.getCityId())
                .platWork(orderServItemTypeDTO.getPlat())
                .productId(orderServItemTypeDTO.getProductId())
                .sourceType(OrderConsts.ORDER_SOURCE_TYPE_NORMAL)
                .type(orderServItemTypeDTO.getType())
                .companyId(companyId)
                .masterId(masterId)
                .beforeServItemType(beforeServItemType)
                .build();
        Integer servItemType = servItemBService.getServItemType(checkQuotationTypeOrderDTO);
        servItemTypeVO.setServItemType(servItemType);


        // 非计价器3.0显示默认服务项
        if (!Objects.equals(servItemTypeVO.getServItemType(), OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE) && !Objects.equals(servItemTypeVO.getServItemType(), OrderConsts.SERVICE_ITEM_TYPE_FINAL_PRICE) ) {
            BackProductPriceQueryDTO build = BackProductPriceQueryDTO
                    .builder()
                    .bizType(orderServItemTypeDTO.getBizType())
                    .showProductId(Objects.equals(orderServItemTypeDTO.getProductShowType(), BaseProductConsts.EC_SHOW_TYPE) ? orderServItemTypeDTO.getProductId() : null)
                    .productId(Objects.equals(orderServItemTypeDTO.getProductShowType(), BaseProductConsts.ERP_SHOW_TYPE) ? orderServItemTypeDTO.getProductId() : null)
                    .brandId(orderServItemTypeDTO.getBrandId())
                    .channelId(orderServItemTypeDTO.getChannelId())
                    .cityId(orderServItemTypeDTO.getCityId())
                    .platWork(orderServItemTypeDTO.getPlat())
                    .build();
            BackProductPriceResultDTO backProductPriceResultDTO = servItemBService.queryBackProductPrice(build);
            if (Objects.isNull(backProductPriceResultDTO)) {
                servItemTypeVO.setIsShow(GlobalConsts.NO);
            }else {
                servItemTypeVO.setPrice(backProductPriceResultDTO.getPrice());
                servItemTypeVO.setUnit(backProductPriceResultDTO.getUnit());
            }
        }else {
            // 计价器3.0取最低价格
            ItemPriceQuery itemPriceQuery = ItemPriceQuery
                    .builder()
                    .bizType(orderServItemTypeDTO.getBizType())
                    .productId(orderServItemTypeDTO.getProductId())
                    .showType(orderServItemTypeDTO.getProductShowType())
                    .brandId(orderServItemTypeDTO.getBrandId())
                    .channelId(orderServItemTypeDTO.getChannelId())
                    .cityId(orderServItemTypeDTO.getCityId())
                    .tariffId(orderServItemTypeDTO.getTariffId())
                    .build();
            logger.info("itemPriceRemoteService.getMinItemPriceByQuery itemPriceQuery={}", itemPriceQuery);
            ResponseDTO<ItemDRO> minItemPriceByQuery = itemPriceRemoteService.getMinItemPriceByQuery(itemPriceQuery);
            logger.info("itemPriceRemoteService.getMinItemPriceByQuery minItemPriceByQuery={}", minItemPriceByQuery);
            if (Objects.isNull(minItemPriceByQuery.getData())) {
                servItemTypeVO.setIsShow(GlobalConsts.NO);
            }else {
                servItemTypeVO.setPrice(minItemPriceByQuery.getData().getPrice());
                servItemTypeVO.setUnit(minItemPriceByQuery.getData().getItemUnit());
            }
        }

        return ResultDTO.success(servItemTypeVO);
    }

    /**
     * 判断工单是否可以修改为返修单
     * @param orderId
     * @param workId
     * @return
     */
    @RequestMapping("/canChangeToRework")
    @ResponseBody
    public ResultDTO canChangeToRework(Long orderId, Long workId) {
        if (Objects.isNull(orderId) || Objects.isNull(workId)) {
            return ResultDTO.success(true);
        }
        //检查工单是否有已支付的金额
        OrderWork orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderId, workId);

        return ResultDTO.success(orderWorkBService.checkCanChangeToRework(orderWork));
    }

    /**
     * 通过手机号和产品查询进行中订单数量
     * @param phone 手机号
     * @param servCategId 服务分类id
     * @return
     */
    @GetMapping("/same/number")
    @ResponseBody
    public ResultDTO getSameOrderNumber(String phone, Integer servCategId) {
        if (StringUtil.isBlank(phone) || NumberUtil.isNullOrZero(servCategId)) {
            return ResultDTO.fail("失败");
        }
        OrderWorkQuery query = new OrderWorkQuery();
        query.setConcatPhone(phone);
        query.setServCategId(Lists.newArrayList(servCategId));
        query.setWorkResultStatus(OrderStatusConsts.WORK_RESULT_DOING);
        int number = orderWorkListBService.countOrderWorkByQuery(query);
        return ResultDTO.success(number);
    }

}
